
package cn.mj.commonutil;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import java.io.*;



public class ZipUtil {
	

	
	static final int ZIP_BUFFER = 4 * 1024;

	
	public static String zipDirectory(String directory) {
		String zipName = directory + ".zip";
		zipDirectory(directory, zipName);
		return zipName;
	}

	
	public static void zipDirectory(String directory, String zipName) {
		try {
			BufferedInputStream origin = null;
			FileOutputStream dest = new FileOutputStream(zipName);
			ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
					dest));
			int endpos = directory.lastIndexOf('/');

			byte data[] = new byte[ZIP_BUFFER];
			// get a list of files from current directory
			File f = new File(directory);
			String files[] = getRecursiveFileList(f);

			for (int i = 0; i < files.length; i++) {
				
				FileInputStream fi = new FileInputStream(files[i]);
				origin = new BufferedInputStream(fi, ZIP_BUFFER);
				String fileName = files[i];

				String relativeName = fileName.substring(endpos + 1,
						fileName.length());
				// assume that host is on UNIX and replaces slashes
				relativeName = relativeName.replace('\\', '/');

				ZipEntry entry = new ZipEntry(relativeName);
				out.putNextEntry(entry);
				int count;
				while ((count = origin.read(data, 0, ZIP_BUFFER)) != -1) {
					out.write(data, 0, count);
				}
				origin.close();
			}

			out.close();
		} catch (Exception e) {
			
		}
	}

	/**
	 * Unzip a file. The file may contain files and directories.
	 * 
	 * @param fileName
	 *            the name of the zip file.
	 * @return the name of the unziped file or directory.
	 */
	public static String unzipFile(String fileName) throws IOException {
		BufferedOutputStream dest = null;
		BufferedInputStream is = null;
		ZipEntry entry;
		ZipFile zipfile = new ZipFile(fileName);
		Enumeration<? extends ZipEntry> e = zipfile.entries();
		File f = new File(fileName);
		String zipFilePath = f.getParent();
		String rootFileName = null;
		String lastRoot = null;
		boolean rootIsOne = true;
		while (e.hasMoreElements()) {
			entry = e.nextElement();

			
			is = new BufferedInputStream(zipfile.getInputStream(entry));

			String entryName = entry.getName();
			int p = entryName.indexOf(File.separator);
			if (p < 0) {
				rootFileName = entryName;
			} else {
				rootFileName = entryName.substring(0, p);
			}
			if (null != lastRoot) {
				if (!rootFileName.equals(lastRoot)) {
					rootIsOne = false;
				}
				lastRoot = rootFileName;
			}

			String entryFileName = zipFilePath + File.separator
					+ entry.getName();
			File zipFileEntry = new File(entryFileName);
			File zipFileDir = zipFileEntry.getParentFile();
			zipFileDir.mkdirs();

			int count;
			byte data[] = new byte[ZIP_BUFFER];
			FileOutputStream fos = new FileOutputStream(entryFileName);
			dest = new BufferedOutputStream(fos, ZIP_BUFFER);
			while ((count = is.read(data, 0, ZIP_BUFFER)) != -1) {
				dest.write(data, 0, count);
			}

			dest.flush();
			dest.close();
			is.close();
			fos.close();
		}

		zipfile.close();
		String rootPath;
		if (rootIsOne) {
			rootPath = zipFilePath + File.separator + rootFileName;
		} else {
			rootPath = zipFilePath;
		}
		return rootPath;
	}
	
	
//	public static String unzipFile(String fileName,String despath) throws IOException {
//		BufferedOutputStream dest = null;
//		BufferedInputStream is = null;
//		ZipEntry entry;
//		ZipFile zipfile = new ZipFile(fileName);
//		Enumeration<? extends ZipEntry> e = zipfile.entries();
//		//File f = new File(fileName);
//		String zipFilePath =despath;
//		String rootFileName = null;
//		String lastRoot = null;
//		boolean rootIsOne = true;
//		while (e.hasMoreElements()) {
//			entry = e.nextElement();
//
//			logger.debug("Extracting: " + entry);
//			is = new BufferedInputStream(zipfile.getInputStream(entry));
//
//			String entryName = entry.getName();
//			int p = entryName.indexOf(File.separator);
//			if (p < 0) {
//				rootFileName = entryName;
//			} else {
//				rootFileName = entryName.substring(0, p);
//			}
//			if (null != lastRoot) {
//				if (!rootFileName.equals(lastRoot)) {
//					rootIsOne = false;
//				}
//				lastRoot = rootFileName;
//			}
//
//			String entryFileName = zipFilePath + File.separator
//					+ entry.getName();
//			File zipFileEntry = new File(entryFileName);
//			File zipFileDir = zipFileEntry.getParentFile();
//			zipFileDir.mkdirs();
//
//			int count;
//			byte data[] = new byte[ZIP_BUFFER];
//			FileOutputStream fos = new FileOutputStream(entryFileName);
//			dest = new BufferedOutputStream(fos, ZIP_BUFFER);
//			while ((count = is.read(data, 0, ZIP_BUFFER)) != -1) {
//				dest.write(data, 0, count);
//			}
//
//			dest.flush();
//			dest.close();
//			is.close();
//			fos.close();
//		}
//
//		zipfile.close();
//		String rootPath;
//		if (rootIsOne) {
//			rootPath = zipFilePath + File.separator + rootFileName;
//		} else {
//			rootPath = zipFilePath;
//		}
//		return rootPath;
//	}
	
	
	public static String unzipFile(String fileName,String despath) throws IOException {
		ZipFile zfile = null;
		String rootPath = despath;
		zfile = new ZipFile(fileName);
		try {

			
			Enumeration zList = zfile.entries();
			ZipEntry ze = null;
			byte data[] = new byte[ZIP_BUFFER];
			while (zList.hasMoreElements()) {
				ze = (ZipEntry) zList.nextElement();
				if (ze.isDirectory()) {
					continue;
				}

				InputStream is = new BufferedInputStream(zfile
						.getInputStream(ze));
				
				OutputStream os = new BufferedOutputStream(
						new FileOutputStream(getRealFileName(despath, ze
								.getName())));

				int count = 0;
				try {
					while ((count = is.read(data, 0, ZIP_BUFFER)) != -1) {
						os.write(data, 0, count);
					}
				} finally {
					if (is != null) {
						is.close();
					}
					if (os != null) {
						os.close();
					}
				}
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();

		} finally {
			if (zfile != null) {
				try {
					zfile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return rootPath;
	}
	
	private static File getRealFileName(String despath, String absFileName) {
		if (!despath.endsWith("/")) {
			despath = despath + "/";
		}
		File file = new File(despath + absFileName);
		
		File parentFile = new File(file.getParent());
		if (!parentFile.exists()) {
			parentFile.mkdirs();
		}
		return file;
	}

	/**
	 * Returns a list of files within the given directory
	 * 
	 * @param f
	 *            the directory to list.
	 * @return the list fo files.
	 */
	public static String[] getRecursiveFileList(File f) {
		Vector<String> v = new Vector<String>();

		String[] files = f.list();
		if (files == null) {
			return new String[0];
		}

		for (int i = 0; i < files.length; i++) {
			File subFile = new File(f.getAbsolutePath() + File.separator
					+ files[i]);
			if (subFile.isDirectory()) {
				String[] childFiles = getRecursiveFileList(subFile);
				for (int j = 0; j < childFiles.length; j++) {
					v.add(childFiles[j]);
				}
			} else {
				v.add(subFile.getPath());
			}
		}

		return (String[]) v.toArray(new String[v.size()]);
	}

	public static void main(String argv[]) throws Exception {

	}

}
